package com.dinglian.ots.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dinglian.ots.common.ToolUtils;
import com.dinglian.ots.common.model.Constant;
import com.dinglian.ots.dao.mapper.*;
import com.dinglian.ots.dao.model.*;
import com.dinglian.ots.exception.GlobalException;
import com.dinglian.ots.redis.RedisService;
import com.dinglian.ots.redis.TopKey;
import com.dinglian.ots.result.CodeMsg;
import com.dinglian.ots.service.BrandService;
import com.dinglian.ots.vo.brand.*;
import com.dinglian.ots.vo.buyer.ApplicationVo;
import com.dinglian.ots.vo.buyer.BuyerMsgVo;
import com.dinglian.ots.vo.buyer.InviteVo;
import com.dinglian.ots.vo.buyer.SearchBuyerVo;
import com.dinglian.ots.vo.order.*;
import com.dinglian.ots.vo.product.CategoryVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.SneakyThrows;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.streaming.*;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @author wangbo
 */
@Service
public class BrandServiceImpl implements BrandService {

    @Value("${pic.path}")
    private String path;

    @Value("${pic.url}")
    private String url;

    @Value("${address}")
    private String address;


    @Autowired
    private BrandMapper brandMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private RelationMapper relationMapper;

    @Autowired
    private MessageMapper messageMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private CategoryRelationMapper categoryRelationMapper;

    @Autowired
    private UserRelationMapper userRelationMapper;

    @Autowired
    private BrandRuleMapper brandRuleMapper;

    @Autowired
    private ParamRelationMapper paramRelationMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private StoreMapper storeMapper;

    @Override
    public PageInfo<BrandVo> getBrandList(Integer userId, Integer categoryId, String keyword, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        if (userId == null) {
            userId = 0;
        }
        List<BrandVo> brandVos = brandMapper.getBrandList(userId, categoryId, keyword);
        return new PageInfo<>(brandVos);
    }

    @Override
    public PageInfo<BrandVo> getRecommendBrand(Integer pageNum, Integer pageSize, Integer categoryId) {
        PageHelper.startPage(pageNum, pageSize);
        List<BrandVo> brandList = brandMapper.getRecommendBrand(categoryId);
        return new PageInfo<>(brandList);
    }

    @Override
    public PageInfo<BrandTopVo> getRecommendTopBrand(Integer pageNum, Integer pageSize, Integer categoryId) {
        PageHelper.startPage(pageNum, pageSize);
        List<BrandTopVo> brandList = brandMapper.getRecommendTopBrand(categoryId);
        return new PageInfo<>(brandList);
    }

    @Override
    public Set<TopBrandVo> getTopBillboard(Integer pageNum, Integer pageSize, Integer sort, Integer categoryId) {
        //判断redis中是否有排行榜信息  暂定1小时刷新一次
        boolean exists = redisService.exists(TopKey.getKey, Constant.TOP_BRAND);
        Set<String> topBrands = new HashSet<>();
        if (exists) {
            //从redis中直接排序返回
            topBrands = redisService.sort(TopKey.getKey, Constant.TOP_BRAND + categoryId, sort, pageNum, pageSize);
        } else {
            //从数据库中查询 并塞入redis
            List<TopBrandVo> brandList = brandMapper.getTopBillboard(categoryId);
            topBrands = redisService.hset(TopKey.getKey, Constant.TOP_BRAND + categoryId, brandList, Constant.TOP_OBJECT_NAME, sort, pageNum, pageSize);
        }
        //将json的String字符串转成对象并返回
        Set<TopBrandVo> brandRank = new LinkedHashSet<>();
        Iterator<String> iterator = topBrands.iterator();
        while (iterator.hasNext()) {
            String topBrand = iterator.next();
            TopBrandVo topBrandVo = JSONObject.parseObject(topBrand, TopBrandVo.class);
            brandRank.add(topBrandVo);
        }
        return brandRank;
    }

    @Override
    public BrandDetailVo getBrandDetail(Integer userId, Integer brandId) {

        BuyerMsgVo buyerMsgVo = storeMapper.getStoreByBuyerId(userId);
        boolean isAudited = false;
        if (buyerMsgVo != null){
            int status = buyerMsgVo.getStatus();
            if (status == 2){
                isAudited= true;
            }
        }

        Map brandMap = brandMapper.getBrandDetail(userId, brandId);

        BrandDetailVo brandDetailVo = new BrandDetailVo();
        brandDetailVo.setAudit(isAudited);
        brandDetailVo.setParentId((Long) brandMap.get("parentId"));
        brandDetailVo.setWebsite((String) brandMap.get("website"));
        brandDetailVo.setStory((String) brandMap.get("story"));
        brandDetailVo.setName((String) brandMap.get("name"));
        brandDetailVo.setMiniOrderQuantity((String) brandMap.get("miniOrderQuantity"));
        brandDetailVo.setEstablishedIn((String) brandMap.get("establishedIn"));
        brandDetailVo.setId(brandId);
        brandDetailVo.setLogo((String) brandMap.get("logo"));
        brandDetailVo.setDesignerIntroduction((String) brandMap.get("designerIntroduction"));
        String lookbook = (String) brandMap.get("lookbook");
        JSONArray jsonArray = JSONArray.parseArray(lookbook);
        brandDetailVo.setPictureList(jsonArray);
        Long isCollected = (Long) brandMap.get("isCollected");
        if (isCollected == 0) {
            brandDetailVo.setCollected(false);
        } else {
            brandDetailVo.setCollected(true);
        }
        Long isPass = (Long) brandMap.get("isPass");
        if (isPass == 0) {
            brandDetailVo.setPass(false);
        } else {
            brandDetailVo.setPass(true);
        }
        Integer ifParent = (Integer) brandMap.get("ifParent");
        if (ifParent == 0) {
            brandDetailVo.setIfParent(false);
        } else {
            brandDetailVo.setIfParent(true);
            List<Map> childBrandList = brandMapper.getChildBrand(brandId);
            brandDetailVo.setChildBrandList(childBrandList);
        }
        return brandDetailVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void agreeIntention(AgreeVo agreeVo) {
        Integer relationId = agreeVo.getRelationId();
        boolean isPass = agreeVo.isPass();
        Relation relation = relationMapper.selectByPrimaryKey(relationId);
        Integer buyerId = relation.getBuyerId();
        BrandWithBLOBs brand = brandMapper.selectByPrimaryKey(relation.getBrandId());
        Message message = new Message();
        message.setUserId(buyerId);

        //查询子品牌
        Integer brandId = relation.getBrandId();
        List<Map> childBrand = brandMapper.getChildBrand(brandId);
        if (isPass) {
            relation.setIsPass(true);
            relation.setId(relationId);
            relation.setType(3);
            relation.setLastUpdateTime(DateUtil.date());
            relationMapper.updateByPrimaryKeySelective(relation);

            //成功
            message.setTitle("您已通过" + brand.getName() + "的审核");
            message.setMessage("您已通过" + brand.getName() + "的审核");
        } else {
            relation.setId(relationId);
            relation.setIsPass(false);
            relation.setLastUpdateTime(DateUtil.date());
            relation.setType(4);
            relationMapper.updateByPrimaryKeySelective(relation);
            //失败
            message.setTitle("您未通过" + brand.getName() + "的审核");
            message.setMessage("您未通过" + brand.getName() + "的审核");
        }

        if (!childBrand.isEmpty()){
            for (int i = 0; i < childBrand.size(); i++) {
                Map map = childBrand.get(i);
                Integer id = (Integer) map.get("id");
                relation.setBrandId(id);
                relationMapper.insertSelective(relation);
            }
        }

        messageMapper.insertSelective(message);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void synchronizeBrandInfo(JSONObject jsonObject, String phone) {
        UserExample userExample = new UserExample();
        userExample.or().andUsernameEqualTo(phone);
        List<User> users = userMapper.selectByExample(userExample);
        Integer userId = null;
        boolean isExistUser = false;
        if (!users.isEmpty()) {
            isExistUser = true;
            User user = users.get(0);
            userId = user.getId();
        }
        Integer showroomId = null;
        String data = jsonObject.getString("data");
        if (data == null) {
            throw new GlobalException(CodeMsg.BRAND_IS_NOT_FOUND);
        }
        JSONObject json = JSONObject.parseObject(data);
        String type = json.getString("type");
        String vip = json.getString("vip");
        String expiration = json.getString("expiration");
        long now = System.currentTimeMillis() / 1000;
        if ((Long.parseLong(expiration) - now) <= 0) {
            throw new GlobalException(CodeMsg.BRAND_EXPIRATION);
        }

        if (Constant.SHOWROOM.equals(type)) {
            JSONArray brandArray = json.getJSONArray(Constant.BRAND);
            if (!isExistUser) {
                User user = new User();
                user.setUsername(phone);
                user.setAvailable(true);
                user.setLevel(Integer.valueOf(vip));
                String showroomName = json.getString("showroom_name");
                user.setName(showroomName);
                user.setRoleId(Constant.SHOWROOM_ROLE);
                user.setIsFirst(false);
                userMapper.insertSelective(user);
                userId = user.getId();
                showroomId = saveShowroomBrand(json, userId);
            }
            for (int i = 0; i < brandArray.size(); i++) {
                JSONObject brandJson = brandArray.getJSONObject(i);
              /*  String brandName = brandJson.getString("brand_name");
                BrandExample brandExample = new BrandExample();
                brandExample.or().andNameEqualTo(brandName);
                List<BrandWithBLOBs> brands = brandMapper.selectByExampleWithBLOBs(brandExample);
                if (brands.isEmpty()) {
                } else {
                    BrandWithBLOBs brand = brands.get(0);
                    updateBrand(brandJson, brand);
                }*/
                Integer brandId = saveBrand(brandJson, true, showroomId);
                UserRelation userRelation = new UserRelation();
                userRelation.setTargetId(brandId);
                userRelation.setUserId(userId);
                userRelation.setType(Constant.TYPE_BRAND);
                userRelationMapper.insertSelective(userRelation);
            }
        } else if (Constant.BRAND.equals(type)) {
            if (!isExistUser) {
                User user = new User();
                user.setUsername(phone);
                user.setAvailable(true);
                user.setLevel(Integer.valueOf(vip));
                String brandName = json.getString("brand_name");
                user.setName(brandName);
                user.setRoleId(Constant.BRAND_ROLE);
                user.setIsFirst(false);
                userMapper.insertSelective(user);
                userId = user.getId();

            }
            Integer brandId = saveBrand(json, false, showroomId);
            UserRelation userRelation = new UserRelation();
            userRelation.setTargetId(brandId);
            userRelation.setUserId(userId);
            userRelation.setType(Constant.TYPE_BRAND);
            userRelationMapper.insertSelective(userRelation);
           /* String brandName = json.getString("brand_name");
            BrandExample brandExample = new BrandExample();
            brandExample.or().andNameEqualTo(brandName);
            List<BrandWithBLOBs> brands = brandMapper.selectByExampleWithBLOBs(brandExample);
            if (brands.isEmpty()) {

            } else {
                updateBrand(json, brands.get(0));
            }*/
        }
    }

    /**
     * 添加品牌信息
     *
     * @param json
     */
    private Integer saveBrand(JSONObject json, boolean isShowroom, Integer showroomId) {
        String logo = json.getString("logo");
        String brandName = json.getString("brand_name");
        String establishment = json.getString("establishment");
        String website = json.getString("website");
        String moq = json.getString("moq");
        String introduction = json.getString("introduction");
        JSONArray jsonArray = json.getJSONArray("category");
        String lookbook = json.getString("lookbook");

        BrandWithBLOBs brand = new BrandWithBLOBs();
        brand.setWebsite(website);
        brand.setLookbook(lookbook);
        brand.setName(brandName);
        brand.setMiniOrderQuantity(moq);
        brand.setLogo(logo);
        brand.setEstablishedIn(establishment);
        brand.setDesignerIntroduction(introduction);
        brand.setIsShow(true);
        brand.setIfParent(false);
        if (isShowroom) {
            brand.setParentId(showroomId);
        } else {
            brand.setParentId(0);
        }

        brandMapper.insertSelective(brand);

        Integer brandId = brand.getId();

        List<Integer> categoryIdList = new ArrayList<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            String categoryName = jsonArray.getString(i);
            Integer categoryId = categoryMapper.getCategoryIdByName(categoryName);
            if (categoryId == null) {
                Category category = new Category();
                category.setParentId(0);
                category.setNameCn(categoryName);
                category.setIsShow(1);
                category.setSort(1);
                categoryMapper.insertSelective(category);
                categoryId = category.getId();
            }
            categoryIdList.add(categoryId);
        }
        categoryRelationMapper.insertCategoryRelation(categoryIdList, brandId, 2);
        return brandId;
    }


    private Integer saveShowroomBrand(JSONObject json, Integer userId) {
        String vip = json.getString("vip");
        String showroomName = json.getString("showroom_name");
        String establishment = json.getString("establishment");

        BrandWithBLOBs brandWithBLOBs = new BrandWithBLOBs();
        brandWithBLOBs.setName(showroomName);
        brandWithBLOBs.setEstablishedIn(establishment);
        brandWithBLOBs.setVip(vip);
        brandWithBLOBs.setParentId(0);
        brandWithBLOBs.setIfParent(true);
        brandWithBLOBs.setIsShow(true);
        brandMapper.insertSelective(brandWithBLOBs);
        Integer brandId = brandWithBLOBs.getId();

        UserRelation userRelation = new UserRelation();
        userRelation.setTargetId(brandId);
        userRelation.setUserId(userId);
        userRelation.setType(Constant.TYPE_BRAND);
        userRelationMapper.insertSelective(userRelation);

        return brandId;
    }

    /**
     * 更新品牌信息
     *
     * @param json
     */
    private void updateBrand(JSONObject json, BrandWithBLOBs brand) {
        String logo = json.getString("logo");
        String brandName = json.getString("brand_name");
        String establishment = json.getString("establishment");
        String website = json.getString("website");
        String moq = json.getString("moq");
        String introduction = json.getString("introduction");
        JSONArray jsonArray = json.getJSONArray("category");
        String lookbook = json.getString("lookbook");

        brand.setWebsite(website);
        brand.setLookbook(lookbook);
        brand.setName(brandName);
        brand.setMiniOrderQuantity(moq);
        brand.setLogo(logo);
        brand.setEstablishedIn(establishment);
        brand.setDesignerIntroduction(introduction);
        brand.setIsShow(true);
        brandMapper.updateByPrimaryKeySelective(brand);

        Integer brandId = brand.getId();
        CategoryRelationExample categoryRelationExample = new CategoryRelationExample();
        categoryRelationExample.or().andTargetIdEqualTo(brandId).andTypeEqualTo(Constant.TYPE_BRAND);
        categoryRelationMapper.deleteByExample(categoryRelationExample);

        List<Integer> categoryIdList = new ArrayList<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            String categoryName = jsonArray.getString(i);
            Integer categoryId = categoryMapper.getCategoryIdByName(categoryName);
            if (categoryId == null) {
                Category category = new Category();
                category.setParentId(0);
                category.setNameCn(categoryName);
                category.setIsShow(1);
                category.setSort(1);
                categoryMapper.insertSelective(category);
                categoryId = category.getId();
            }
            categoryIdList.add(categoryId);
        }
        categoryRelationMapper.insertCategoryRelation(categoryIdList, brandId, 2);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBrandInfo(SaveBrandVo brandVo) {
        BrandWithBLOBs brand = new BrandWithBLOBs();
        brand.setId(brandVo.getBrandId());
        brand.setDesignerSchool(brandVo.getDesignerSchool());
        brand.setDesignerName(brandVo.getDesignerName());
        brand.setName(brandVo.getName());
        brand.setEstablishedIn(brandVo.getEstablishedIn());
        brand.setDesignerIntroduction(ToolUtils.urlDecoder(brandVo.getDesignerIntroduction()));
        brand.setStory(ToolUtils.urlDecoder(brandVo.getStory()));
        brand.setWebsite(brandVo.getWebsite());
        brand.setMiniOrderQuantity(brandVo.getMiniOrderQuantity());
        MultipartFile logo = brandVo.getLogo();
        if (logo != null) {
            String logoFileId = ToolUtils.uploadPicture(path, brandVo.getName(), Constant.BRAND_LOGO, logo);
            brand.setLogo(url + logoFileId);
        }
        MultipartFile[] lookbooks = brandVo.getLookbook();
        if (lookbooks != null) {
            JSONArray fileNames = new JSONArray();
            for (int i = 0; i < lookbooks.length; i++) {
                MultipartFile lookbook = lookbooks[i];
                String lookbookFileId = ToolUtils.uploadPicture(path, brandVo.getName(), Constant.BRAND_LOOKBOOK, lookbook);
                fileNames.add(url + lookbookFileId);
            }
            brand.setLookbook(fileNames.toString());
        }
        brandMapper.updateByPrimaryKeySelective(brand);

        String categoryIds = brandVo.getCategoryIds();
        if (categoryIds != null) {
            CategoryRelationExample categoryRelationExample = new CategoryRelationExample();
            categoryRelationExample.or().andTargetIdEqualTo(brandVo.getBrandId()).andTypeEqualTo(Constant.TYPE_BRAND);
            categoryRelationMapper.deleteByExample(categoryRelationExample);

            String[] categoryList = categoryIds.split(",");
            for (int i = 0; i < categoryList.length; i++) {
                String categoryId = categoryList[i];
                CategoryRelation categoryRelation = new CategoryRelation();
                categoryRelation.setCategoryId(Integer.valueOf(categoryId));
                categoryRelation.setTargetId(brandVo.getBrandId());
                //1店铺 2品牌 3商品
                categoryRelation.setType(Constant.TYPE_BRAND);
                categoryRelationMapper.insertSelective(categoryRelation);
            }
        }
        Integer styleId = brandVo.getStyleId();
        Integer crowdId = brandVo.getCrowdId();
        Integer prId = paramRelationMapper.getParamRelationId(brandVo.getBrandId(), 1);
        if (prId == null) {
            ParamRelation paramRelation = new ParamRelation();
            paramRelation.setTargetId(brandVo.getBrandId());
            paramRelation.setType(Constant.TYPE_BRAND);
            paramRelation.setStyleId(styleId);
            paramRelationMapper.insertSelective(paramRelation);
        } else {
            ParamRelation paramRelation = new ParamRelation();
            paramRelation.setId(prId);
            paramRelation.setStyleId(styleId);
            paramRelationMapper.updateByPrimaryKeySelective(paramRelation);

        }
        prId = paramRelationMapper.getParamRelationId(brandVo.getBrandId(), 2);
        if (prId == null) {
            ParamRelation paramRelation = new ParamRelation();
            paramRelation.setTargetId(brandVo.getBrandId());
            paramRelation.setType(Constant.TYPE_BRAND);
            paramRelation.setStyleId(crowdId);
            paramRelationMapper.insertSelective(paramRelation);
        } else {
            ParamRelation paramRelation = new ParamRelation();
            paramRelation.setId(prId);
            paramRelation.setStyleId(crowdId);
            paramRelationMapper.updateByPrimaryKeySelective(paramRelation);
        }


    }

    @Override
    public void setBrandOrderRule(BrandRuleVo brandRuleVo) {
        BrandRule brandRule = new BrandRule();
        brandRule.setStandardAmount(brandRuleVo.getStandardAmount());
        brandRule.setSaleMethod(brandRuleVo.getSaleMethod());
        BigDecimal preAmount = new BigDecimal(brandRuleVo.getPreferentialAmount());
        BigDecimal amount = preAmount.multiply(new BigDecimal(10));
        brandRule.setPreferentialAmount(amount.toString());
        brandRule.setOrderRule(brandRuleVo.getOrderRule());
        brandRule.setBrandId(brandRuleVo.getBrandId());
        brandRuleMapper.insertSelective(brandRule);
    }

    @Override
    public BrandInfoVo getBrandInfo(Integer brandId) {
        BrandWithBLOBs brand = brandMapper.selectByPrimaryKey(brandId);
        if (brand == null) {
            throw new GlobalException(CodeMsg.BRAND_INFO_IS_NOT_FOUND);
        }

        BrandInfoVo brandInfoVo = new BrandInfoVo();
        BeanUtils.copyProperties(brand, brandInfoVo);

        List<CategoryVo> categoryVos = categoryMapper.getCategoryByBrandId(brandId);
        brandInfoVo.setCategoryIds(categoryVos);

        Integer styleId = paramRelationMapper.getParamByBrandId(brandId, 1);
        brandInfoVo.setStyleId(styleId);
        Integer crowdId = paramRelationMapper.getParamByBrandId(brandId, 2);
        brandInfoVo.setCrowdId(crowdId);

        return brandInfoVo;
    }

    @Override
    public List<BrandRuleInfoVo> getBrandOrderRule(Integer brandId) {
        return brandRuleMapper.getBrandOrderRule(brandId);
    }

    @Override
    public void deleteBrandOrderRule(Integer ruleId) {
        brandRuleMapper.deleteByPrimaryKey(ruleId);
    }

    @Override
    public PageInfo<BuyerOrderVo> brandElectionOrder(Integer brandId, Integer seasonId, Integer pageNum, Integer pageSize) {
        List<BuyerOrderVo> buyerOrderVos = new ArrayList<>();
        PageHelper.startPage(pageNum, pageSize);
        buyerOrderVos = orderMapper.selectElectionOrderByBuyer(brandId, seasonId);
        for (int i = 0; i < buyerOrderVos.size(); i++) {
            BuyerOrderVo buyerOrderVo = buyerOrderVos.get(i);
            Double totalAmount = buyerOrderVo.getTotalAmount();
            Integer totalQuantity = buyerOrderVo.getTotalQuantity();
            BigDecimal balance = calculateLadderPrice1(brandId, new BigDecimal(totalAmount), totalQuantity);
            buyerOrderVo.setTotalAmount(balance.doubleValue());

        }

        return new PageInfo<>(buyerOrderVos);
    }


    @Override
    public void exportBrandElectionOrder(Integer userId, Integer seasonId, Integer brandId, HttpServletResponse response) {
        BufferedImage bufferImg = null;
        SXSSFWorkbook wb = new SXSSFWorkbook();

        List<Map> list = orderMapper.exportBrandElectionOrder(userId, seasonId, brandId);
        BigDecimal totalAmount = BigDecimal.ZERO;
        Integer totalQuantity  = 0;
        if (list.isEmpty()) {
            throw new GlobalException(CodeMsg.DONT_TOUCH_ME);
        }
        try {
            SXSSFSheet sheet = wb.createSheet("选款单");

            SXSSFDrawing drawingPatriarch = sheet.createDrawingPatriarch();
            SXSSFRow rowCn = sheet.createRow(0);
            String discountAmt = null;
            String storeName = null;
            for (int i = 0; i < Constant.PRODUCT_EXCEL_CN.length; i++) {
                SXSSFCell cell = rowCn.createCell(i);
                cell.setCellType(CellType.STRING);
                sheet.setColumnWidth(i, 5000);
                cell.setCellValue(Constant.PRODUCT_EXCEL_CN[i]);
            }
            SXSSFRow rowEn = sheet.createRow(1);
            for (int i = 0; i < Constant.PRODUCT_EXCEL_EN.length; i++) {
                SXSSFCell cell = rowEn.createCell(i);
                cell.setCellType(CellType.STRING);
                cell.setCellValue(Constant.PRODUCT_EXCEL_EN[i]);
            }
            for (int i = 0; i < list.size(); i++) {
                Map map = list.get(i);
                SXSSFRow row = sheet.createRow(i + 2);
                row.setHeight((short) 2000);
                //图片
                String whitePic = ToolUtils.objectToString(map.get("whitePic"));
                if (!StrUtil.isBlank(whitePic)) {
                    whitePic = whitePic.replaceAll(url, path);
                    ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
                    //将两张图片读到BufferedImage
                    File file = new File(whitePic);
                    if (file.exists()) {
                        bufferImg = ImageIO.read(file);
                        ImageIO.write(bufferImg, "png", byteArrayOut);
                        /**
                         * 该构造函数有8个参数
                         * 前四个参数是控制图片在单元格的位置，分别是图片距离单元格left，top，right，bottom的像素距离
                         * 后四个参数，前连个表示图片左上角所在的cellNum和 rowNum，后天个参数对应的表示图片右下角所在的cellNum和 rowNum，
                         * excel中的cellNum和rowNum的index都是从0开始的
                         *
                         */
                        //图片一导出到单元格B2中
                        XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 255, 255, (short) 0, i + 2, (short) 1, i + 3);
                        // 插入图片
                        drawingPatriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), XSSFWorkbook.PICTURE_TYPE_JPEG));
                    }
                }

                //linesheet
                SXSSFCell cell = row.createCell(1);
                cell.setCellType(CellType.STRING);
                String name = ToolUtils.objectToString(map.get("productName"));
                cell.setCellValue(name);

                //订货季
                cell = row.createCell(2);
                cell.setCellType(CellType.STRING);
                String seasonName = ToolUtils.objectToString(map.get("seasonName"));
                cell.setCellValue(seasonName);

                //款式名称
                cell = row.createCell(3);
                cell.setCellType(CellType.STRING);
                String title = ToolUtils.objectToString(map.get("title"));
                cell.setCellValue(title);

                //款式编码
                cell = row.createCell(4);
                cell.setCellType(CellType.STRING);
                String styleName = ToolUtils.objectToString(map.get("stylename"));
                cell.setCellValue(styleName);

                //颜色
                cell = row.createCell(5);
                cell.setCellType(CellType.STRING);
                String colorName = ToolUtils.objectToString(map.get("colorName"));
                cell.setCellValue(colorName);

                //颜色号
                cell = row.createCell(7);
                cell.setCellType(CellType.STRING);
                String colorValue = ToolUtils.objectToString(map.get("colorValue"));
                cell.setCellValue(colorValue);

                //面料
                cell = row.createCell(8);
                cell.setCellType(CellType.STRING);
                String fabrication = ToolUtils.objectToString(map.get("fabrication"));
                cell.setCellValue(fabrication);

                //材质
                cell = row.createCell(10);
                cell.setCellType(CellType.STRING);
                String materials = ToolUtils.objectToString(map.get("materials"));
                cell.setCellValue(materials);

                //商品描述
                cell = row.createCell(11);
                cell.setCellType(CellType.STRING);
//                String description = ToolUtils.objectToString(map.get("description"));
                String description = "";
                cell.setCellValue(description);

                //分类
                cell = row.createCell(12);
                cell.setCellType(CellType.STRING);
                String categoryName = ToolUtils.objectToString(map.get("categoryName"));
                cell.setCellValue(categoryName);

                //二级分类
                cell = row.createCell(13);
                cell.setCellType(CellType.STRING);
                String subcategoryName = ToolUtils.objectToString(map.get("subcategoryName"));
                cell.setCellValue(subcategoryName);

                //尺码
                cell = row.createCell(14);
                cell.setCellType(CellType.STRING);
                String sizeName = ToolUtils.objectToString(map.get("sizeName"));
                cell.setCellValue(sizeName);

               /* //大货
                cell = row.createCell(15);
                cell.setCellType(CellType.STRING);
                String bulk = ToolUtils.objectToString(map.get("bulk"));
                cell.setCellValue(bulk);*/

                //OS
                cell = row.createCell(15);
                cell.setCellType(CellType.STRING);
                String OS = ToolUtils.objectToString(map.get("OS"));
                cell.setCellValue(OS);

                //XS
                cell = row.createCell(16);
                cell.setCellType(CellType.STRING);
                String XS = ToolUtils.objectToString(map.get("XS"));
                cell.setCellValue(XS);

                //S
                cell = row.createCell(17);
                cell.setCellType(CellType.STRING);
                String S = ToolUtils.objectToString(map.get("S"));
                cell.setCellValue(S);

                //M
                cell = row.createCell(18);
                cell.setCellType(CellType.STRING);
                String M = ToolUtils.objectToString(map.get("M"));
                cell.setCellValue(M);

                //L
                cell = row.createCell(19);
                cell.setCellType(CellType.STRING);
                String L = ToolUtils.objectToString(map.get("L"));
                cell.setCellValue(L);

                //XL
                cell = row.createCell(20);
                cell.setCellType(CellType.STRING);
                String XL = ToolUtils.objectToString(map.get("XL"));
                cell.setCellValue(XL);

                //XXL
                cell = row.createCell(21);
                cell.setCellType(CellType.STRING);
                String XXL = ToolUtils.objectToString(map.get("XXL"));
                cell.setCellValue(XXL);

                //35
                cell = row.createCell(22);
                cell.setCellType(CellType.STRING);
                String tf = ToolUtils.objectToString(map.get("tf"));
                cell.setCellValue(tf);

                //35½
                cell = row.createCell(23);
                cell.setCellType(CellType.STRING);
                String tfh = ToolUtils.objectToString(map.get("tfh"));
                cell.setCellValue(tfh);

                //36
                cell = row.createCell(24);
                cell.setCellType(CellType.STRING);
                String ts = ToolUtils.objectToString(map.get("ts"));
                cell.setCellValue(ts);

                //36½
                cell = row.createCell(25);
                cell.setCellType(CellType.STRING);
                String tsh = ToolUtils.objectToString(map.get("tsh"));
                cell.setCellValue(tsh);

                //37
                cell = row.createCell(26);
                cell.setCellType(CellType.STRING);
                String tse = ToolUtils.objectToString(map.get("tse"));
                cell.setCellValue(tse);

                //37½
                cell = row.createCell(27);
                cell.setCellType(CellType.STRING);
                String tseh = ToolUtils.objectToString(map.get("tseh"));
                cell.setCellValue(tseh);

                //38
                cell = row.createCell(28);
                cell.setCellType(CellType.STRING);
                String te = ToolUtils.objectToString(map.get("te"));
                cell.setCellValue(te);

                //38½
                cell = row.createCell(29);
                cell.setCellType(CellType.STRING);
                String teh = ToolUtils.objectToString(map.get("teh"));
                cell.setCellValue(teh);

                //39
                cell = row.createCell(30);
                cell.setCellType(CellType.STRING);
                String tn = ToolUtils.objectToString(map.get("tn"));
                cell.setCellValue(tn);

                //39½
                cell = row.createCell(31);
                cell.setCellType(CellType.STRING);
                String tnh = ToolUtils.objectToString(map.get("tnh"));
                cell.setCellValue(tnh);

                //40
                cell = row.createCell(32);
                cell.setCellType(CellType.STRING);
                String fty = ToolUtils.objectToString(map.get("fty"));
                cell.setCellValue(fty);

                //40½
                cell = row.createCell(33);
                cell.setCellType(CellType.STRING);
                String ftyh = ToolUtils.objectToString(map.get("ftyh"));
                cell.setCellValue(ftyh);

                //41
                cell = row.createCell(34);
                cell.setCellType(CellType.STRING);
                String fo = ToolUtils.objectToString(map.get("fo"));
                cell.setCellValue(fo);

                //41½
                cell = row.createCell(35);
                cell.setCellType(CellType.STRING);
                String foh = ToolUtils.objectToString(map.get("foh"));
                cell.setCellValue(foh);

                //42
                cell = row.createCell(36);
                cell.setCellType(CellType.STRING);
                String ft = ToolUtils.objectToString(map.get("ft"));
                cell.setCellValue(ft);

                //42½
                cell = row.createCell(37);
                cell.setCellType(CellType.STRING);
                String fth = ToolUtils.objectToString(map.get("fth"));
                cell.setCellValue(fth);

                //43
                cell = row.createCell(38);
                cell.setCellType(CellType.STRING);
                String ftt = ToolUtils.objectToString(map.get("ftt"));
                cell.setCellValue(ftt);

                //43½
                cell = row.createCell(39);
                cell.setCellType(CellType.STRING);
                String ftth = ToolUtils.objectToString(map.get("ftth"));
                cell.setCellValue(ftth);

                //44
                cell = row.createCell(40);
                cell.setCellType(CellType.STRING);
                String ff = ToolUtils.objectToString(map.get("ff"));
                cell.setCellValue(ff);

                //订货价
                cell = row.createCell(41);
                cell.setCellType(CellType.STRING);
                String costPrice = ToolUtils.objectToString(map.get("costPrice"));
                cell.setCellValue(costPrice);

                //建议零售价
                cell = row.createCell(42);
                cell.setCellType(CellType.STRING);
                String sellingPrice = ToolUtils.objectToString(map.get("sellingPrice"));
                cell.setCellValue(sellingPrice);

                BigDecimal costPriceBig = new BigDecimal(costPrice);
                BigDecimal sellingPriceBig = new BigDecimal(sellingPrice);

                //订货折扣  订货价/建议零售价
                cell = row.createCell(43);
                cell.setCellType(CellType.STRING);
                BigDecimal markDown = costPriceBig.divide(sellingPriceBig,2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(10));
//                String markDown = ToolUtils.objectToString(map.get("markDown"));
                cell.setCellValue(markDown.toString());

                //倍率  建议零售价/订货价
                cell = row.createCell(44);
                cell.setCellType(CellType.STRING);
                BigDecimal markUp = sellingPriceBig.divide(costPriceBig, 2, RoundingMode.HALF_UP);
//                String markUp = ToolUtils.objectToString(map.get("markUp"));
                cell.setCellValue(markUp.toString());

                //单位
                cell = row.createCell(46);
                cell.setCellType(CellType.STRING);
                String units = ToolUtils.objectToString(map.get("units"));
                cell.setCellValue(units);

                //单色最小订量
                cell = row.createCell(48);
                cell.setCellType(CellType.STRING);
                String totalQty = ToolUtils.objectToString(map.get("totalQty"));
                cell.setCellValue(totalQty);

                //最终单款价格
                cell = row.createCell(49);
                cell.setCellType(CellType.STRING);




                //订货总额  满减之后的价格 最后一行展示
                discountAmt = ToolUtils.objectToString(map.get("discountAmt"));

                cell = row.createCell(50);
                cell.setCellType(CellType.STRING);
                BigDecimal totalAmt = new BigDecimal(costPrice).multiply(new BigDecimal(totalQty)).setScale(2,RoundingMode.HALF_UP);
                cell.setCellValue(totalAmt.toString());


                totalAmount = totalAmount.add(totalAmt);
                totalQuantity += Integer.valueOf(totalQty);

                //零售总额
                cell = row.createCell(51);
                cell.setCellType(CellType.STRING);
                String totalRetail = ToolUtils.objectToString(map.get("totalRetail"));
                cell.setCellValue(totalRetail);

                BigDecimal discountAmtBig = new BigDecimal(discountAmt);

                //折扣  1-(零售总额/订货总额)*100
                cell = row.createCell(45);
                cell.setCellType(CellType.STRING);
                BigDecimal discount = (BigDecimal.ONE).subtract(costPriceBig.divide(sellingPriceBig,2,BigDecimal.ROUND_HALF_UP));
//                String discount = ToolUtils.objectToString(map.get("discount"));
//                cell.setCellValue(discount.toString());
//                BigDecimal discount = (BigDecimal.ONE).subtract(markDown);
                cell.setCellValue((discount.multiply(new BigDecimal(100))).toString());

                storeName = ToolUtils.objectToString(map.get("storeName"));
            }
            SXSSFRow row = sheet.createRow(list.size() + 3);
            SXSSFCell cell = row.createCell(50);
            cell.setCellType(CellType.STRING);
            BigDecimal balanceAmt =  calculateLadderPrice1(brandId,totalAmount,totalQuantity);
            cell.setCellValue(balanceAmt.toString());

            response.reset();
            //response为HttpServletResponse对象
            response.setContentType("application/octet-stream;charset=utf-8");


            String fileName = null;
            try {
                fileName = URLEncoder.encode(storeName + "的选款单", "UTF-8");
                fileName = new String(fileName.getBytes("utf-8"), "ISO-8859-1");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            //test.xls是弹出下载对话框的文件名，不能为中文，中文请自行编码
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
            ServletOutputStream out = null;
            out = response.getOutputStream();
            wb.write(out);
            wb.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void inviteBuyer(InviteVo inviteVo) {
        Integer buyerId = inviteVo.getBuyerId();
        Integer brandId = inviteVo.getBrandId();
        RelationExample relationExample = new RelationExample();
        relationExample.or().andBrandIdEqualTo(brandId).andBuyerIdEqualTo(buyerId);
        List<Relation> relations = relationMapper.selectByExample(relationExample);

        //查询brandId所对应的userId
        Integer userId = userMapper.selectUserIdByTargetId(brandId, Constant.TYPE_BRAND);
        if (userId == null) {
            throw new GlobalException(CodeMsg.USER_ID_NOT_FOUND);
        }
        Integer relationId = null;
        if (!relations.isEmpty()) {
            Relation relation = relations.get(0);
            relationId = relation.getId();
        } else {
            //保存关联关系表
            Relation relation = new Relation();
            relation.setBuyerId(buyerId);
            relation.setBrandId(brandId);
            relation.setIsPass(false);
            relation.setType(1);
            relationMapper.insertSelective(relation);
            relationId = relation.getId();
        }
        BrandWithBLOBs brandWithBLOBs = brandMapper.selectByPrimaryKey(brandId);

        //组成文案
        //保存站内信
        Message message = new Message();
        message.setUserId(buyerId);
        message.setTitle("您有新的品牌邀请");

        StringBuilder sb = new StringBuilder();
        sb.append("<span>品牌：" + brandWithBLOBs.getName()+"向您发出了邀请</span>").append("<br>");
        message.setMessage(sb.toString());
        messageMapper.insertSelective(message);

    }

    @Override
    public PageInfo<SearchBuyerVo> inviteBuyerList(Integer brandId, Integer type, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<SearchBuyerVo> searchBuyerVos = relationMapper.inviteBuyerList(brandId,type);
        return new PageInfo<>(searchBuyerVos);
    }


    @Override
    public void setReturnRatio(ReturnRatioVo returnRatioVo) {
        RelationExample relationExample = new RelationExample();
        relationExample.or().andBuyerIdEqualTo(returnRatioVo.getBuyerId()).andBrandIdEqualTo(returnRatioVo.getBrandId());
        Relation relation = new Relation();
        relation.setReturnRatio(returnRatioVo.getReturnRatio());
        relationMapper.updateByExampleSelective(relation,relationExample);
    }


    @Override
    public void setIsInterested(Integer brandId, Integer storeId) {
        UserRelationExample userRelationExample = new UserRelationExample();
        userRelationExample.or().andTargetIdEqualTo(storeId).andTypeEqualTo(Constant.TYPE_STORE);
        List<UserRelation> userRelations = userRelationMapper.selectByExample(userRelationExample);
        if (!userRelations.isEmpty()){
            UserRelation userRelation = userRelations.get(0);
            Integer buyerId = userRelation.getUserId();
            Relation relation = new Relation();
            relation.setBuyerId(buyerId);
            relation.setBrandId(brandId);
            relation.setIsInterested(false);
            relation.setIsPass(false);
            relation.setType(4);
            relationMapper.insertSelective(relation);
        }

    }

    @Override
    public boolean isAuthSuccess(Integer userId, Integer brandId) {
        RelationExample relationExample = new RelationExample();
        relationExample.or().andBuyerIdEqualTo(userId).andBrandIdEqualTo(brandId);
        List<Relation> relations = relationMapper.selectByExample(relationExample);
        if (!relations.isEmpty()){
            Relation relation = relations.get(0);
            boolean isPass = relation.getIsPass();
            if (isPass){
                return  true;
            }else{
                return false;
            }
        }
        return false;
    }

    @Override
    public Integer selectBrandParentId(Integer userId) {

        UserRelationExample userRelationExample = new UserRelationExample();
        userRelationExample.or().andTargetIdEqualTo(userId).andTypeEqualTo(Constant.TYPE_BRAND);
        List<UserRelation> userRelations = userRelationMapper.selectByExample(userRelationExample);
        if (!userRelations.isEmpty()){
            UserRelation userRelation  = userRelations.get(0);
            return  userRelation.getUserId();
        }else{
            return null;
        }

    }

    /**
     * 计算折后价格
     */
    public BigDecimal calculateLadderPrice1(Integer brandId, BigDecimal totalAmt, Integer totalQty) {


        //先判断是否含有金额规则或者数量规则
        BrandRuleExample amtbrandRuleExample = new BrandRuleExample();
        amtbrandRuleExample.or().andBrandIdEqualTo(brandId).andOrderRuleEqualTo(1);
        List<BrandRule> amtbrandRuleList = brandRuleMapper.selectByExample(amtbrandRuleExample);

        BrandRuleExample qtybrandRuleExample = new BrandRuleExample();
        qtybrandRuleExample.or().andBrandIdEqualTo(brandId).andOrderRuleEqualTo(2);
        List<BrandRule> qtyBrandRuleList = brandRuleMapper.selectByExample(qtybrandRuleExample);

        List<BigDecimal> balanceList = new ArrayList<>();

        if (!amtbrandRuleList.isEmpty()) {
            //金额
            List<Map> brandRules = brandRuleMapper.getAmtRuleByBrandId(brandId, totalAmt);
            if (brandRules.isEmpty()) {
               /* //满足最高条件
                List<Map> list = brandRuleMapper.satisfyAmtOrderCondition(brandId, totalAmt);
                if (!list.isEmpty()) {
                    Map brandRule = list.get(0);
                    String balance = ToolUtils.objectToString(brandRule.get("balance"));
                    BigDecimal bigDecimal = new BigDecimal(balance);
                    balanceList.add(bigDecimal);
                } else {
                    balanceList.add(new BigDecimal(totalAmt));
                }*/
            } else {
                Map brandRule = brandRules.get(0);
                Double balance = (Double) brandRule.get("balance");
                balanceList.add(new BigDecimal(balance));
            }
        }
        if (!qtyBrandRuleList.isEmpty()) {
            //数量
            List<Map> brandRules = brandRuleMapper.getQtyRuleByBrandId(brandId, totalQty, totalAmt);
            if (brandRules.isEmpty()) {
                /*//满足条件
                List<Map> list = brandRuleMapper.satisfyQtyOrderCondition(brandId, totalQty, totalAmt);
                if (!list.isEmpty()) {
                    Map brandRule = list.get(0);
                    String balance = ToolUtils.objectToString(brandRule.get("balance"));
                    BigDecimal bigDecimal = new BigDecimal(balance);
                    balanceList.add(bigDecimal);
                } else {
                    balanceList.add(new BigDecimal(totalAmt));
                }*/
            } else {
                Map brandRule = brandRules.get(0);
                Double balance = (Double) brandRule.get("balance");
                balanceList.add(new BigDecimal(balance));
            }
        }
        if (balanceList.isEmpty()) {
            balanceList.add(totalAmt);
        }
        BigDecimal min = Collections.min(balanceList);
        return min.setScale(2, BigDecimal.ROUND_HALF_UP);

    }

}
